"""
配置管理模块
管理Docker更新、服务配置等
"""

import json
import os
import logging
from typing import Dict, List, Optional, Any
from pathlib import Path

logger = logging.getLogger(__name__)

class ConfigManager:
    """配置管理器类"""
    
    def __init__(self, config_path: str = None):
        """
        初始化配置管理器
        
        Args:
            config_path: 配置文件路径，默认为项目根目录下的config/update.json
        """
        if config_path is None:
            # 默认配置文件路径
            project_root = Path(__file__).parent.parent.parent
            self.config_path = project_root / "config" / "update.json"
        else:
            self.config_path = Path(config_path)
        
        self._config = None
        self.load_config()
    
    def load_config(self) -> None:
        """加载配置文件"""
        try:
            if not self.config_path.exists():
                logger.error(f"配置文件不存在: {self.config_path}")
                raise FileNotFoundError(f"配置文件不存在: {self.config_path}")
            
            with open(self.config_path, 'r', encoding='utf-8') as f:
                self._config = json.load(f)
            
            logger.info(f"配置文件加载成功: {self.config_path}")
            
        except json.JSONDecodeError as e:
            logger.error(f"配置文件JSON格式错误: {e}")
            raise
        except Exception as e:
            logger.error(f"加载配置文件失败: {e}")
            raise
    
    def save_config(self) -> None:
        """保存配置文件"""
        try:
            # 确保目录存在
            self.config_path.parent.mkdir(parents=True, exist_ok=True)
            
            with open(self.config_path, 'w', encoding='utf-8') as f:
                json.dump(self._config, f, indent=2, ensure_ascii=False)
            
            logger.info(f"配置文件保存成功: {self.config_path}")
            
        except Exception as e:
            logger.error(f"保存配置文件失败: {e}")
            raise
    
    def get_config(self) -> Dict[str, Any]:
        """获取完整配置"""
        return self._config
    
    def get_docker_config(self) -> Dict[str, Any]:
        """获取Docker配置"""
        return self._config.get('docker', {})
    
    def get_registry_config(self) -> Dict[str, Any]:
        """获取Registry配置"""
        docker_config = self.get_docker_config()
        return docker_config.get('registry', {})
    
    def get_registry_url(self) -> str:
        """获取Registry URL"""
        registry_config = self.get_registry_config()
        
        # 根据配置选择使用VPC还是公网地址
        if registry_config.get('use_vpc', True):
            return registry_config.get('url', '')
        else:
            return registry_config.get('public_url', '')
    
    def get_registry_username(self) -> str:
        """获取Registry用户名"""
        registry_config = self.get_registry_config()
        return registry_config.get('username', '')
    
    def get_registry_namespace(self) -> str:
        """获取Registry命名空间"""
        registry_config = self.get_registry_config()
        return registry_config.get('namespace', '')
    
    def get_services_config(self) -> List[Dict[str, Any]]:
        """获取服务配置列表"""
        docker_config = self.get_docker_config()
        return docker_config.get('services', [])
    
    def get_service_config(self, service_name: str) -> Optional[Dict[str, Any]]:
        """获取特定服务的配置"""
        services = self.get_services_config()
        for service in services:
            if service.get('name') == service_name:
                return service
        return None
    
    def get_service_names(self) -> List[str]:
        """获取所有服务名称列表"""
        services = self.get_services_config()
        return [service.get('name', '') for service in services]
    
    def get_service_images(self) -> Dict[str, str]:
        """获取服务名称到本地镜像的映射"""
        services = self.get_services_config()
        return {
            service.get('name', ''): service.get('image', '')
            for service in services
        }
    
    def get_service_remote_images(self) -> Dict[str, str]:
        """获取服务名称到远程镜像的映射"""
        services = self.get_services_config()
        registry_url = self.get_registry_url()
        
        return {
            service.get('name', ''): f"{registry_url}/{service.get('remote_image', '')}"
            for service in services
        }
    
    def get_course_config(self) -> Dict[str, Any]:
        """获取课程配置"""
        return self._config.get('course', {})
    
    def get_schedule_config(self) -> Dict[str, Any]:
        """获取调度配置"""
        return self._config.get('schedule', {})
    
    def get_notification_config(self) -> Dict[str, Any]:
        """获取通知配置"""
        return self._config.get('notification', {})
    
    def get_security_config(self) -> Dict[str, Any]:
        """获取安全配置"""
        return self._config.get('security', {})
    
    def get_network_config(self) -> Dict[str, Any]:
        """获取网络配置"""
        return self._config.get('network', {})
    
    def is_auto_backup_enabled(self) -> bool:
        """检查是否启用自动备份"""
        docker_config = self.get_docker_config()
        return docker_config.get('auto_backup', True)
    
    def get_backup_retention(self) -> int:
        """获取备份保留数量"""
        docker_config = self.get_docker_config()
        return docker_config.get('backup_retention', 5)
    
    def get_update_strategy(self) -> str:
        """获取更新策略"""
        docker_config = self.get_docker_config()
        return docker_config.get('update_strategy', 'rolling')
    
    def get_health_check_timeout(self) -> int:
        """获取健康检查超时时间"""
        docker_config = self.get_docker_config()
        return docker_config.get('health_check_timeout', 60)
    
    def is_network_sharing_enabled(self) -> bool:
        """检查是否启用网络共享"""
        network_config = self.get_network_config()
        shared_config = network_config.get('shared_ethernet', {})
        return shared_config.get('enabled', False)
    
    def get_network_sharing_config(self) -> Dict[str, Any]:
        """获取网络共享配置"""
        network_config = self.get_network_config()
        return network_config.get('shared_ethernet', {})
    
    def update_config(self, section: str, key: str, value: Any) -> None:
        """更新配置项"""
        if section not in self._config:
            self._config[section] = {}
        
        self._config[section][key] = value
        logger.info(f"更新配置: {section}.{key} = {value}")
    
    def update_service_config(self, service_name: str, config_updates: Dict[str, Any]) -> bool:
        """更新特定服务的配置"""
        services = self.get_services_config()
        
        for i, service in enumerate(services):
            if service.get('name') == service_name:
                # 更新服务配置
                services[i].update(config_updates)
                logger.info(f"更新服务配置: {service_name}")
                return True
        
        logger.warning(f"未找到服务: {service_name}")
        return False
    
    def add_service_config(self, service_config: Dict[str, Any]) -> None:
        """添加新的服务配置"""
        docker_config = self.get_docker_config()
        if 'services' not in docker_config:
            docker_config['services'] = []
        
        docker_config['services'].append(service_config)
        logger.info(f"添加新服务配置: {service_config.get('name', 'unknown')}")
    
    def remove_service_config(self, service_name: str) -> bool:
        """移除服务配置"""
        services = self.get_services_config()
        
        for i, service in enumerate(services):
            if service.get('name') == service_name:
                services.pop(i)
                logger.info(f"移除服务配置: {service_name}")
                return True
        
        logger.warning(f"未找到服务: {service_name}")
        return False
    
    def validate_config(self) -> List[str]:
        """验证配置文件的有效性"""
        errors = []
        
        # 检查必要的配置节
        required_sections = ['docker', 'schedule']
        for section in required_sections:
            if section not in self._config:
                errors.append(f"缺少必要的配置节: {section}")
        
        # 检查Docker配置
        docker_config = self.get_docker_config()
        if not docker_config.get('registry', {}).get('url'):
            errors.append("Docker registry URL未配置")
        
        if not docker_config.get('registry', {}).get('username'):
            errors.append("Docker registry用户名未配置")
        
        if not docker_config.get('services'):
            errors.append("Docker服务列表为空")
        
        # 检查服务配置
        services = self.get_services_config()
        for service in services:
            if not service.get('name'):
                errors.append("服务名称未配置")
            if not service.get('image'):
                errors.append(f"服务 {service.get('name', 'unknown')} 的镜像未配置")
        
        return errors
    
    def get_config_summary(self) -> Dict[str, Any]:
        """获取配置摘要信息"""
        registry_config = self.get_registry_config()
        services = self.get_services_config()
        
        return {
            "registry_url": self.get_registry_url(),
            "registry_username": self.get_registry_username(),
            "namespace": self.get_registry_namespace(),
            "services_count": len(services),
            "service_names": self.get_service_names(),
            "auto_backup": self.is_auto_backup_enabled(),
            "update_strategy": self.get_update_strategy(),
            "network_sharing": self.is_network_sharing_enabled(),
            "config_file": str(self.config_path)
        }


# 全局配置管理器实例
config_manager = ConfigManager()


def get_config_manager() -> ConfigManager:
    """获取配置管理器实例"""
    return config_manager


# 便捷函数
def get_registry_url() -> str:
    """获取Registry URL"""
    return config_manager.get_registry_url()

def get_service_names() -> List[str]:
    """获取服务名称列表"""
    return config_manager.get_service_names()

def get_service_images() -> Dict[str, str]:
    """获取服务镜像映射"""
    return config_manager.get_service_images()

def is_auto_backup_enabled() -> bool:
    """检查是否启用自动备份"""
    return config_manager.is_auto_backup_enabled() 